package cvo.pro4.chess.client.entities;

import com.google.gwt.regexp.shared.RegExp;

import cvo.pro4.chess.client.exceptions.IllegalCoordinatesException;


public class BoardCoordinates {
	private Integer x; 
	private Integer y;	
	
	/**
	 * A constructor which takes coordinates like "A1"	
	 * @param coordinates
	 * @throws IllegalCoordinatesException 
	 */
	public static BoardCoordinates create(final String coordinates) throws IllegalCoordinatesException{

		//Make the alphanumericals capital like on a chessboard
		String alpaNumerical = coordinates.substring(0,1).toUpperCase();
		
		//Make sure the coordinates are valid
		validate(coordinates);
			
		//get the char and convert it to a number and increase it to match unicode
		int val = alpaNumerical.charAt(0) - 64;
		Integer x = new Integer(val);
			
		// get the number
		Integer y =  Integer.valueOf(coordinates.substring(1,2));
	
		return new BoardCoordinates(x,y);
		
	}
	
	
	/**
	 * This method support coordinate creation by int parameters
	 * @param x Column (Represents A > H)
	 * @param y Row ( 1 - 8)
	 * @return A Boord
	 * @throws IllegalCoordinatesException
	 */
	public static BoardCoordinates create(final Integer x, final Integer y) throws IllegalCoordinatesException{
		return new BoardCoordinates(x, y);		
	}
	
	private BoardCoordinates(Integer x, Integer y) throws IllegalCoordinatesException{
		validate(x,y);
		this.x = x;
		this.y = y;
	}
	

	/**
	 * Gets the true x-axis coordinate
	 * @return
	 */
	public Integer getX(){
		return this.x;
	}
	
	/**
	 * Gets the true y-axis coordinate
	 * @return
	 */
	public Integer getY(){
		return this.y;
	}

	
	/**
	 * Validates coordinates to see if they are correct, they must match pattern [a-hA-H]{1}[0-8]{1}
	 * @param String the coordinates to be checked
	 * @return boolean true is they are correct
	 * @throws IllegalCoordinatesException 
	 */
	private static void validate(String coordinates) throws IllegalCoordinatesException{
		String regexString = "[a-hA-H]{1}[0-8]{1}";
		RegExp exp =  RegExp.compile(regexString);
		boolean matches = exp.test(coordinates);

		//Check if the input String matches our required pattern
		if(!matches){
		throw new IllegalCoordinatesException("Coordinates \"" + coordinates + "\" are invalid. Input must be a string from A > H and from 1 > 8 ");
		}	
	}
	
	/**
	 * Validates coordinates to see if they are correct. They must be from 1 to 8
	 * @param x
	 * @param y
	 * @throws IllegalCoordinatesException
	 */
	private static void validate(Integer x, Integer y) throws IllegalCoordinatesException{
		if((x < 0 && x > 8) || (y < 0 && y > 8)){
			throw new IllegalCoordinatesException("Coordinates (" + x +"," + y + ") are invalid. Parameters for creation of a BoardCoordinate must be between from 1 to 8");
		}
	}
	
	
	@Override
	public String toString(){	
		// Increase the number to match the unicode value
		Character xCoordinate = Character.toChars(x + 64)[0];
	
		
		String coordinatesPresenter = xCoordinate.toString() + this.y;
		return coordinatesPresenter;
	}
	
	@Override
	public boolean equals(Object other){
		if(other instanceof BoardCoordinates){
			BoardCoordinates otherCoordinates = (BoardCoordinates)other;
			if(this.getX().equals(otherCoordinates.getX()) && this.getY().equals(otherCoordinates.getY())){
				return true;
			}			
		}
		return false;
	}

}